/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package mrp.productionPlanning.session;

import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.ejb.LocalBean;
import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import mrp.productionPlanning.entity.ForecastEntity;
import mrp.productionPlanning.entity.MPSTableEntity;
import mrp.productionPlanning.entity.MonthlyDetailEntity;
import scm.inventoryControl.session.stateless.InventoryControlSessionBean;

/**
 *
 * @author Wei Haoyang
 */
@Stateless
@LocalBean
public class MPSTableSessionBean {

    // Add business logic below. (Right-click in editor and choose
    // "Insert Code > Add Business Method")
    @PersistenceContext
    EntityManager em;
    @EJB
    private MonthlyDetailSessionBean mdsb = new MonthlyDetailSessionBean();
    @EJB
    private ForecastSessionBean fsb = new ForecastSessionBean();
    @EJB
    private InventoryControlSessionBean icsb = new InventoryControlSessionBean();

    public MPSTableEntity createMPSTableA(Date d) {
        Calendar cal = new GregorianCalendar();
        cal.setTime(d);
        int correction = cal.get(Calendar.MONTH);
        System.out.println("Correction: " + correction);
        SimpleDateFormat sdf = new SimpleDateFormat("dd/mm/yyyy");
        System.out.println(d.toString());
        String test = sdf.format(cal.getTime());
        System.out.println(test);
        try {
            d = sdf.parse(test);
        } catch (ParseException ex) {
        }
        System.out.println(d.toString());
        cal.setTime(d);
        cal.set(Calendar.MONTH, correction);
        d = cal.getTime();
        System.out.println(d.toString());
        cal.set(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH), cal.get(Calendar.DATE), 0, 1, 0);
        System.out.println(cal.getTime());
        MPSTableEntity mpsTable = new MPSTableEntity();
        MonthlyDetailEntity monthlyDetail = mdsb.getMonthlyDetailByDate(cal.getTime());
        Timestamp ts = new Timestamp(cal.getTime().getTime());
        mpsTable.setTs(ts);
        String monthName = null;
        DateFormat df = new SimpleDateFormat("MMM");
        System.out.println("Calendar Month :" + cal.get(Calendar.MONTH));
        monthName = df.format(cal.getTime());
        System.out.println(monthName);
        monthName = convertToEnglish(monthName);
        System.out.println(monthName);
        int yearName = cal.get(Calendar.YEAR);
        System.out.println(yearName);
        ForecastEntity forecast = fsb.getForecastEntityByMonth(monthName, yearName);
        System.out.println("Forecast:" + forecast.getAmountA());
        mpsTable.setMonthlyDetailEntity(monthlyDetail);
        System.out.println("Test1...." + mpsTable.getMonthlyDetailEntity().getDate());
        mpsTable.setForecastEntity(forecast);
        mpsTable.setMonthName(monthName);
        mpsTable.setYearName(yearName);
        mpsTable.setProductType("productA");
        mpsTable.getMonthlyDetailEntity().setScheduleA(mpsTable.getForecastEntity().getAmountA());
        mdsb.updateMonthlyDetail(mpsTable.getMonthlyDetailEntity());
        mpsTable.setMonth(d);
        int currentInventory = icsb.getCurrentInventoryLevel("Classic Nutri Bar-Nuts");
        System.out.println("CurrentInventory:" + currentInventory);
        if (monthName.equalsIgnoreCase("Jan")) {
            mpsTable.setInventory(currentInventory - mpsTable.getForecastEntity().getAmountA() + mpsTable.getMonthlyDetailEntity().getScheduleA());
            System.out.println("Inventory: " + mpsTable.getInventory());
        } else {
            Date lastMonth = d;
            cal.setTime(d);
            int cm = 0;
            System.out.println(d.toString());
            cm = cal.get(Calendar.MONTH);
            cm -= 1;
            cal.set(Calendar.MONTH, cm);
            lastMonth = cal.getTime();
            System.out.println("LastMonth:" + lastMonth.toString());
//            lastMonth.setMonth(d.getMonth()-1);
            MPSTableEntity lastMPS = getMPSTableByDate(lastMonth, "productA");
            mpsTable.setInventory(lastMPS.getInventory() - mpsTable.getForecastEntity().getAmountA() + mpsTable.getMonthlyDetailEntity().getScheduleA());
            System.out.println("Inventory: " + mpsTable.getInventory());
        }
        mpsTable.setWorkingDay(monthlyDetail.getDays().size());
        mpsTable.setUtilRate((float)((mpsTable.getMonthlyDetailEntity().getScheduleA()/50)/(21.6*mpsTable.getWorkingDay())));
//        mpsTable.setUtilRate((float)(mpsTable.getMonthlyDetailEntity().getTotalTime()/(21.4*mpsTable.getWorkingDay())));
        addMPSTable(mpsTable);
        return mpsTable;
    }

    public MPSTableEntity createMPSTableB(Date d) {
        Calendar cal = new GregorianCalendar();
        cal.setTime(d);
        int correction = cal.get(Calendar.MONTH);
        System.out.println("Correction: " + correction);
        SimpleDateFormat sdf = new SimpleDateFormat("dd/mm/yyyy");
        String test = sdf.format(d);
        System.out.println(test);
        try {
            d = sdf.parse(test);
        } catch (ParseException ex) {
        }
        cal.setTime(d);
        cal.set(Calendar.MONTH, correction);
        d = cal.getTime();
        System.out.println(d.toString());
        cal.set(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH), cal.get(Calendar.DATE), 0, 1, 0);
        System.out.println(cal.getTime());
        MPSTableEntity mpsTable = new MPSTableEntity();
        MonthlyDetailEntity monthlyDetail = mdsb.getMonthlyDetailByDate(cal.getTime());
        Timestamp ts = new Timestamp(cal.getTime().getTime());
        mpsTable.setTs(ts);
        String monthName = null;
        DateFormat df = new SimpleDateFormat("MMM");
        monthName = df.format(d);
        monthName = convertToEnglish(monthName);
        System.out.println(monthName);
        int yearName = cal.get(Calendar.YEAR);
        System.out.println(yearName);
        ForecastEntity forecast = fsb.getForecastEntityByMonth(monthName, yearName);
        mpsTable.setMonthlyDetailEntity(monthlyDetail);
        mpsTable.setForecastEntity(forecast);
        mpsTable.setMonthName(monthName);
        mpsTable.setYearName(yearName);
        mpsTable.setProductType("productB");
        mpsTable.getMonthlyDetailEntity().setScheduleB(mpsTable.getForecastEntity().getAmountB());
        mdsb.updateMonthlyDetail(mpsTable.getMonthlyDetailEntity());
        mpsTable.setMonth(d);
        int currentInventory = icsb.getCurrentInventoryLevel("Classic Nutri Bar-Fruits");
        if (monthName.equalsIgnoreCase("JAN")) {
            mpsTable.setInventory(currentInventory - mpsTable.getForecastEntity().getAmountA() + mpsTable.getMonthlyDetailEntity().getScheduleA());
        } else {
            Date lastMonth = d;
            cal.setTime(d);
            int cm = 0;
            System.out.println(d.toString());
            cm = cal.get(Calendar.MONTH);
            cm -= 1;
            cal.set(Calendar.MONTH, cm);
            lastMonth = cal.getTime();
            System.out.println("LastMonth:" + lastMonth.toString());
            //lastMonth.setMonth(d.getMonth()-1);
            MPSTableEntity lastMPS = getMPSTableByDate(lastMonth, "productB");
            mpsTable.setInventory(lastMPS.getInventory() - mpsTable.getForecastEntity().getAmountA() + mpsTable.getMonthlyDetailEntity().getScheduleA());
        }
        mpsTable.setWorkingDay(monthlyDetail.getDays().size());
        mpsTable.setUtilRate((float)((mpsTable.getMonthlyDetailEntity().getScheduleB()/50)/(21.6*mpsTable.getWorkingDay())));
//        mpsTable.setUtilRate((float)(mpsTable.getMonthlyDetailEntity().getTotalTime()/(21.4*mpsTable.getWorkingDay())));
        addMPSTable(mpsTable);
        return mpsTable;
    }

    public MPSTableEntity createMPSTableC(Date d) {
        Calendar cal = new GregorianCalendar();
        cal.setTime(d);
        int correction = cal.get(Calendar.MONTH);
        System.out.println("Correction: " + correction);
        SimpleDateFormat sdf = new SimpleDateFormat("dd/mm/yyyy");
        String test = sdf.format(d);
        System.out.println(test);
        try {
            d = sdf.parse(test);
        } catch (ParseException ex) {
        }
        cal.setTime(d);
        cal.set(Calendar.MONTH, correction);
        d = cal.getTime();
        System.out.println(d.toString());
        cal.set(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH), cal.get(Calendar.DATE), 0, 1, 0);
        System.out.println(cal.getTime());
        MPSTableEntity mpsTable = new MPSTableEntity();
        MonthlyDetailEntity monthlyDetail = mdsb.getMonthlyDetailByDate(cal.getTime());
        Timestamp ts = new Timestamp(cal.getTime().getTime());
        mpsTable.setTs(ts);
        String monthName = null;
        DateFormat df = new SimpleDateFormat("MMM");
        monthName = df.format(d);
        monthName = convertToEnglish(monthName);
        System.out.println("monthName: " + monthName);
        int yearName = cal.get(Calendar.YEAR);
        System.out.println("yearName: " + yearName);
        ForecastEntity forecast = fsb.getForecastEntityByMonth(monthName, yearName);
        mpsTable.setMonthlyDetailEntity(monthlyDetail);
        mpsTable.setForecastEntity(forecast);
        mpsTable.setMonthName(monthName);
        mpsTable.setYearName(yearName);
        mpsTable.setProductType("productC");
        mpsTable.setMonth(d);
        mpsTable.getMonthlyDetailEntity().setScheduleC(mpsTable.getForecastEntity().getAmountC());
        mdsb.updateMonthlyDetail(mpsTable.getMonthlyDetailEntity());
        int currentInventory = icsb.getCurrentInventoryLevel("Premium Power Bar-Chocolate Nuts");
        if (monthName.equalsIgnoreCase("JAN")) {
            mpsTable.setInventory(currentInventory - mpsTable.getForecastEntity().getAmountA() + mpsTable.getMonthlyDetailEntity().getScheduleA());
        } else {
            Date lastMonth = d;
            cal.setTime(d);
            int cm = 0;
            System.out.println(d.toString());
            cm = cal.get(Calendar.MONTH);
            cm -= 1;
            cal.set(Calendar.MONTH, cm);
            lastMonth = cal.getTime();
            // lastMonth.setMonth(d.getMonth()-1);
            MPSTableEntity lastMPS = getMPSTableByDate(lastMonth, "productC");
            mpsTable.setInventory(lastMPS.getInventory() - mpsTable.getForecastEntity().getAmountA() + mpsTable.getMonthlyDetailEntity().getScheduleA());
        }
        mpsTable.setWorkingDay(monthlyDetail.getDays().size());
        mpsTable.setUtilRate((float)((mpsTable.getMonthlyDetailEntity().getScheduleC()/45)/(21.6*mpsTable.getWorkingDay())));
//        mpsTable.setUtilRate((float)(mpsTable.getMonthlyDetailEntity().getTotalTime()/(21.4*mpsTable.getWorkingDay())));
        addMPSTable(mpsTable);
        return mpsTable;
    }

    public MPSTableEntity createMPSTableD(Date d) {
        Calendar cal = new GregorianCalendar();
        cal.setTime(d);
        int correction = cal.get(Calendar.MONTH);
        System.out.println("Correction: " + correction);
        SimpleDateFormat sdf = new SimpleDateFormat("dd/mm/yyyy");
        String test = sdf.format(d);
        System.out.println(test);
        try {
            d = sdf.parse(test);
        } catch (ParseException ex) {
        }
        cal.setTime(d);
        cal.set(Calendar.MONTH, correction);
        d = cal.getTime();
        System.out.println(d.toString());
        cal.set(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH), cal.get(Calendar.DATE), 0, 1, 0);
        System.out.println(cal.getTime());
        MPSTableEntity mpsTable = new MPSTableEntity();
        MonthlyDetailEntity monthlyDetail = mdsb.getMonthlyDetailByDate(cal.getTime());
        Timestamp ts = new Timestamp(cal.getTime().getTime());
        mpsTable.setTs(ts);
        String monthName = null;
        DateFormat df = new SimpleDateFormat("MMM");
        monthName = df.format(d);
        monthName = convertToEnglish(monthName);
        System.out.println("monthName: " + monthName);
        int yearName = cal.get(Calendar.YEAR);
        System.out.println("yearName: " + yearName);
        ForecastEntity forecast = fsb.getForecastEntityByMonth(monthName, yearName);
        mpsTable.setMonthlyDetailEntity(monthlyDetail);
        mpsTable.setForecastEntity(forecast);
        mpsTable.setMonthName(monthName);
        mpsTable.setYearName(yearName);
        mpsTable.setProductType("productD");
        mpsTable.setMonth(d);
        mpsTable.getMonthlyDetailEntity().setScheduleD(mpsTable.getForecastEntity().getAmountD());
        mdsb.updateMonthlyDetail(mpsTable.getMonthlyDetailEntity());
        int currentInventory = icsb.getCurrentInventoryLevel("Premium Power Bar-Redcurrant Fruits");
        if (monthName.equalsIgnoreCase("JAN")) {
            mpsTable.setInventory(currentInventory - mpsTable.getForecastEntity().getAmountA() + mpsTable.getMonthlyDetailEntity().getScheduleA());
        } else {
            Date lastMonth = d;
            cal.setTime(d);
            int cm = 0;
            System.out.println(d.toString());
            cm = cal.get(Calendar.MONTH);
            cm -= 1;
            cal.set(Calendar.MONTH, cm);
            lastMonth = cal.getTime();
            //lastMonth.setMonth(d.getMonth()-1);
            MPSTableEntity lastMPS = getMPSTableByDate(lastMonth, "productD");
            mpsTable.setInventory(lastMPS.getInventory() - mpsTable.getForecastEntity().getAmountA() + mpsTable.getMonthlyDetailEntity().getScheduleA());
        }
        mpsTable.setWorkingDay(monthlyDetail.getDays().size());
        mpsTable.setUtilRate((float)((mpsTable.getMonthlyDetailEntity().getScheduleD()/45)/(21.6*mpsTable.getWorkingDay())));
//        mpsTable.setUtilRate((float)(mpsTable.getMonthlyDetailEntity().getTotalTime()/(21.4*mpsTable.getWorkingDay())));
        addMPSTable(mpsTable);
        return mpsTable;
    }

    public MPSTableEntity getMPSTableByDate(Date d, String type) {
        int correction = 0;
        Calendar cal = new GregorianCalendar();
        cal.setTime(d);
        correction = cal.get(Calendar.MONTH);
        SimpleDateFormat sdf = new SimpleDateFormat("dd/mm/yyyy");
        String temp = sdf.format(d);
        try {
            d = sdf.parse(temp);
        } catch (ParseException ex) {
        }
        cal.setTime(d);
        cal.set(Calendar.MONTH, correction);
        d = cal.getTime();
        Timestamp ts = new Timestamp(d.getTime());
        System.out.println(d.toString());
        System.out.println(ts.toString());
        ts.setMinutes(1);
       
        Query query = em.createQuery("SELECT u FROM MPSTableEntity u WHERE u.ts = :dd AND u.productType = :type");
        query.setParameter("dd", ts);
        query.setParameter("type", type);
        MPSTableEntity dd = null;
        try {
            dd = (MPSTableEntity) query.getSingleResult();
        } catch (NoResultException ex) {
            throw ex;
        }
        return dd;
    }

    public MPSTableEntity getMPSTableEntityByMonth(String monthName, String type, int y) {
        MPSTableEntity mPSTableEntity = new MPSTableEntity();
        Query query = em.createQuery("SELECT u FROM MPSTableEntity u where u.productType = :dd AND u.monthName = :mm AND u.yearName = :yy order by u.month");
        query.setParameter("mm",monthName);
        query.setParameter("dd", type);
        query.setParameter("yy", y);
        
        try {
            mPSTableEntity = (MPSTableEntity) query.getSingleResult();
        } catch (NoResultException ex) {
            throw ex;
        }
        return mPSTableEntity;
    }

    public List<MPSTableEntity> getAllMPSTableEntityByProduct(String type, int y) {
        List<MPSTableEntity> out = new ArrayList<MPSTableEntity>();
        Query query = em.createQuery("SELECT u FROM MPSTableEntity u WHERE u.productType = :dd AND u.yearName = :yy order by u.month");
        query.setParameter("dd", type);
        query.setParameter("yy", y);
        out = (List<MPSTableEntity>) query.getResultList();
        return out;
    }

    public String convertToEnglish(String in) {
        String out = in;
        if (in.equalsIgnoreCase("一月")) {
            out = "Jan";
        } else if (in.equalsIgnoreCase("二月")) {
            out = "Feb";
        } else if (in.equalsIgnoreCase("三月")) {
            out = "Mar";
        } else if (in.equalsIgnoreCase("四月")) {
            out = "Apr";
        } else if (in.equalsIgnoreCase("五月")) {
            out = "May";
        } else if (in.equalsIgnoreCase("六月")) {
            out = "Jun";
        } else if (in.equalsIgnoreCase("七月")) {
            out = "Jul";
        } else if (in.equalsIgnoreCase("八月")) {
            out = "Aug";
        } else if (in.equalsIgnoreCase("九月")) {
            out = "Sep";
        } else if (in.equalsIgnoreCase("十月")) {
            out = "Oct";
        } else if (in.equalsIgnoreCase("十一月")) {
            out = "Nov";
        } else if (in.equalsIgnoreCase("十二月")) {
            out = "Dec";
        }
        return out;
    }
    
    public List<MPSTableEntity> getMPSTableByYear(int y){
        Query query = em.createQuery("SELECT f FROM MPSTableEntiy f where f.yearName = :dd");
        query.setParameter("dd", y);
        List<MPSTableEntity> mpsList = query.getResultList();
//        List<MPSTableEntity> output = new ArrayList<MPSTableEntity>();
//        for(MPSTableEntity mps: mpsList){
//            if (mps.getMonth().getYear()==(y-1900)){
//                output.add(mps);
//            }
//        }
        return mpsList;
    }

    public void addMPSTable(MPSTableEntity mps) {
        em.persist(mps);
        em.flush();
    }

    public void updateMPSTable(MPSTableEntity mps) {
        em.merge(mps);
        em.flush();
    }
}
